home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / smlltalk / smtk_11.zoo / Date.st < prev    next >
Text File  |  1990-05-26  |  7KB  |  285 lines

  1. "======================================================================
  2. |
  3. |   Date Method Definitions
  4. |
  5.  ======================================================================"
  6.  
  7.  
  8. "======================================================================
  9. |
  10. | Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
  11. | Written by Steve Byrne.
  12. |
  13. | This file is part of GNU Smalltalk.
  14. |
  15. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  16. | under the terms of the GNU General Public License as published by the Free
  17. | Software Foundation; either version 1, or (at your option) any later version.
  18. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  19. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  20. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  21. | details.
  22. | You should have received a copy of the GNU General Public License along with
  23. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  24. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  25. |
  26.  ======================================================================"
  27.  
  28.  
  29. "
  30. |     Change Log
  31. | ============================================================================
  32. | Author       Date       Change 
  33. | sbyrne     25 Apr 89      created.
  34. |
  35. "
  36.  
  37. Magnitude subclass: #Date
  38.       instanceVariableNames: 'days'
  39.       classVariableNames: ''
  40.       poolDictionaries: ''
  41.       category: nil.
  42.  
  43. Date comment: 
  44. 'My instances represent dates.  My base date is defined to be Jan 1, 1901.
  45. I provide methods for instance creation (including via "symbolic" dates, 
  46. such as "Date newDay: 14 month: #Feb year: 1990"' !
  47.  
  48. Smalltalk at: #DayNameDict put: Dictionary new!
  49. Smalltalk at: #MonthNameDict put: Dictionary new!
  50.  
  51. !Date class methodsFor: 'basic'!
  52.  
  53. initialize
  54.     self initDayNameDict.
  55.     self initMonthNameDict
  56. !
  57.  
  58. initDayNameDict
  59.     | dayNames |
  60.     dayNames _ #(
  61.                  (monday mon)    "1"
  62.                  (tuesday tue)    "2"
  63.                  (wednesday wed) "3"
  64.                  (thursday thu) "4"
  65.                  (friday fri)    "5"
  66.                  (saturday sat) "6"
  67.                  (sunday sun)    "7"
  68.                 ).
  69.     1 to: dayNames size do:
  70.         [ :dayIndex | (dayNames at: dayIndex) do:
  71.         [ :name | DayNameDict at: name put: dayIndex ] ].
  72. !
  73.  
  74. initMonthNameDict
  75.     | monthNames |
  76.     monthNames _ #(
  77.                  (january   jan)    "1"
  78.                  (february  feb)    "2"
  79.                  (march        mar)        "3"
  80.                  (april        apr)        "4"
  81.                  (may)                    "5"
  82.                  (june        jun)        "6"
  83.                  (july        jul)    "7"
  84.                  (august    aug)    "8"
  85.                  (september sep)    "9"
  86.                  (october   oct)    "10"
  87.                  (november  nov)    "11"
  88.                  (december  dec)    "12"
  89.                 ).
  90.     1 to: monthNames size do:
  91.         [ :monthIndex | (monthNames at: monthIndex) do:
  92.         [ :name | MonthNameDict at: name put: monthIndex ] ].
  93. !
  94.  
  95.  
  96. dayOfWeek: dayName
  97.     ^DayNameDict at: dayName asLowercase asSymbol
  98. !
  99.  
  100. nameOfDay: dayIndex
  101.     ^#(Monday Tuesday Wednesday Thursday Friday Saturday Sunday) at: dayIndex
  102. !
  103.  
  104. indexOfMonth: monthName
  105.     ^MonthNameDict at: monthName asLowercase asSymbol
  106. !
  107.  
  108. nameOfMonth: monthIndex
  109.     ^#(January February  March
  110.        April   May       June
  111.        July    August    September
  112.        October November  December) at: monthIndex
  113. !
  114.  
  115. daysInMonth: monthName forYear: yearInteger
  116.     | monthIndex |
  117.     monthIndex _ self indexOfMonth: monthName.
  118.     ^self daysInMonthIndex: monthIndex forYear: yearInteger
  119. !
  120.  
  121. daysInYear: yearInteger
  122.     ^365 + (self leapYear: yearInteger)
  123. !
  124.  
  125. leapYear: yearInteger
  126.     (yearInteger \\ 4 = 0
  127.         and: [ yearInteger \\ 100 ~= 0
  128.         or: [ yearInteger \\ 400 = 0 ] ]) 
  129.         ifTrue: [ ^1 ]
  130.     ifFalse: [ ^0 ]
  131. !
  132.  
  133. dateAndTimeNow
  134.     ^Array with: (Date today) with: (Time now)
  135. !!
  136.  
  137.  
  138.  
  139. !Date class methodsFor: 'instance creation'!
  140.  
  141. today
  142.     | now date |
  143.     now _ Time secondClock.
  144.     date _ now / (24 * 60 * 60).
  145.     ^self new setDays: date  + 25202 "(69 * 365 + 17)"
  146. !
  147.  
  148. fromDays: dayCount
  149.     ^self new setDays: dayCount
  150. !
  151.  
  152. newDay: dayCount year: yearInteger
  153.     ^self new setDays: (dayCount + self yearAsDays: yearInteger)
  154. !
  155.  
  156. newDay: day month: monthName year: yearInteger
  157.     ^self new setDays:
  158.         (day + (self daysUntilMonth: monthName year: yearInteger)
  159.              + (self yearAsDays: yearInteger))
  160. !!
  161.  
  162.  
  163.  
  164. !Date class methodsFor: 'private methods'!
  165.  
  166. yearAsDays: yearInteger
  167.     "Returns the number of days since Jan 1, 1901."
  168.     yearInteger _ yearInteger - 1900.
  169.     ^(yearInteger - 1) * 365
  170.         + (yearInteger // 4)
  171.     - (yearInteger // 100)
  172.     + (yearInteger // 400)
  173. !
  174.  
  175. daysUntilMonth: monthName year: yearInteger
  176.     | monthIndex totalDays |
  177.     totalDays _ 0.
  178.     monthIndex _ self indexOfMonth: monthName.
  179.     1 to: monthIndex - 1 do:
  180.         [ :index | totalDays _ totalDays + (self daysInMonthIndex: index
  181.                                              forYear: yearInteger) ].
  182.     ^totalDays
  183. !
  184.  
  185.  
  186. daysInMonthIndex: monthIndex forYear: yearInteger
  187.     | days |
  188.     days _ #(31 28 31        "Jan Feb Mar"
  189.             30 31 30        "Apr May Jun"
  190.         31 31 30        "Jul Aug Sep"
  191.         31 30 31        "Oct Nov Dec"
  192.         ) at: monthIndex.
  193.     monthIndex = 2
  194.         ifTrue: [ ^days + (self leapYear: yearInteger) ]
  195.     ifFalse: [ ^days ]
  196.  
  197. !!
  198.  
  199.  
  200. !Date methodsFor: 'basic'!
  201.  
  202. addDays: dayCount
  203.     days _ days + dayCount
  204. !
  205.  
  206. subtractDays: dayCount
  207.     days _ days - dayCount
  208. !
  209.  
  210. subtractDate: aDate
  211.     ^days - aDate days
  212. !!
  213.  
  214.  
  215.  
  216. !Date methodsFor: 'printing'!
  217.  
  218. printOn: aStream
  219.     self computeDateParts:
  220.         [ :year :month :day |
  221.         day printOn: aStream.
  222.            aStream nextPut: $-.
  223.         ((Date nameOfMonth: month) copyFrom: 1 to: 3) printOn: aStream.
  224.            aStream nextPut: $-.
  225.         year \\ 100 printOn: aStream ]
  226. !!
  227.  
  228.  
  229.  
  230. !Date methodsFor: 'storing'!
  231.  
  232. storeOn: aStream
  233.     "Won't work past around 1200 years in the future"
  234.     aStream nextPut: $(.
  235.     aStream nextPutAll: self classNameString.
  236.     self computeDateParts:
  237.         [ :year :month :day |
  238.         aStream nextPutAll: ' newDay: '.
  239.         day storeOn: aStream.
  240.         aStream nextPutAll: ' month: '.
  241.             (Date nameOfMonth: month) storeOn: aStream.
  242.         aStream nextPutAll: ' year: '.
  243.         year storeOn: aStream ].
  244.     aStream nextPut: $)
  245. !!
  246.  
  247.  
  248.  
  249. !Date methodsFor: 'private methods'!
  250.  
  251. days
  252.     ^days
  253. !
  254.  
  255. setDays: dayCount
  256.     days _ dayCount
  257. !
  258.  
  259. computeDateParts: aBlock
  260.     | yearInteger tempDays monthIndex daysInMonth |
  261.     tempDays _ days - (days // 1460) "4*365"
  262.                     + (days // 36500) "100*365"
  263.             - (days // 146000). "400*365"
  264.     yearInteger _ tempDays // 365.
  265.     "The +1 below makes tempDays be 1 based, instead of 0 based, so that the
  266.      first day is 1 Jan 1901 instead of 0 jan 1901"
  267.     tempDays _ days - (yearInteger * 365)
  268.             - (yearInteger // 4)
  269.             + (yearInteger // 100)
  270.             - (yearInteger // 400)
  271.             + 1.
  272.     yearInteger _ yearInteger + 1901.
  273.     monthIndex _ 1.
  274.     [ monthIndex < 12
  275.         and: [ daysInMonth _ Date daysInMonthIndex: monthIndex
  276.                               forYear: yearInteger.
  277.                tempDays > daysInMonth ] ] whileTrue:
  278.         [ monthIndex _ monthIndex + 1.
  279.       tempDays _ tempDays - daysInMonth ].
  280.     ^aBlock value: yearInteger value: monthIndex value: tempDays
  281. !!
  282.  
  283.